package it.poli.IA;

import it.poli.IA.TilesGame.TileActionEnum;
import it.poli.IA.TilesGame.TileAction;
import it.poli.IA.TilesGame.TileNode;
import it.poli.IA.TilesGame.TileState;
import it.poli.IA.exceptions.FailureException;
import it.poli.IA.space.Action;
import it.poli.IA.space.State;
import it.poli.IA.strategies.Strategies;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

public class MainTiles {

	/**
	 * @param args
	 * @throws FailureException 
	 */
	public static void main(String[] args)  {
		
		DecisionModule decModule = new DecisionModule();
		
		  int[][] matrix = new int[][] {{1, 2, 3}  ,
				  						{4, 5, 6}  ,
				  						{7, 8, 0} 
				  						};
		 
		  boolean youAreInMood=true;
		 if(youAreInMood)
		  matrix = new int[][] {{1, 2,  3,  4  }  ,
								{5, 6,  7,  8  }  ,
								{9, 10, 11, 12 }  ,
								{13, 14, 15, 0 }  
								};
		
		TileState currentState = new TileState(matrix);
		

		
		currentState.performRandomMoves(500);
		
		
		
		System.out.println("\n\n\n Problem is : " + currentState +  " Now is time: " + new Date());
		
		TileNode n0 = new TileNode(currentState);
		
		List<TileAction> actions = new ArrayList<TileAction>();
		actions.add(new TileAction(TileActionEnum.up));
		actions.add(new TileAction(TileActionEnum.down));
		actions.add(new TileAction(TileActionEnum.left));
		actions.add(new TileAction(TileActionEnum.right));
		
		State g = n0.getCurrentState().getSameDimensionGoalState();
		List<State> Goals = new ArrayList<State>();
		Goals.add(g);
		
		System.out.println("\n\n Goal is: "+ g);
		
		try
		{
			TileState.useSumOfDistance = true;//if false will use misplaced tiles
			Collection<? extends it.poli.IA.space.Action> solution = 
					decModule.SomeSearch(n0, actions, Goals,
							Strategies.Astar_GraphSearch
							);
			
			System.out.println("\n\n\n Solution is : " + solution);
			System.out.println("\n\n\n Solution HR is : " );
			convertToHumanMove(solution);
			
			System.out.println(" now is time :  " + new Date());
		
		}
		catch(FailureException eff)
		{
			System.out.println(" failed ");
		}

	}
	
	
	private static void convertToHumanMove(Collection<? extends Action> solution)
	{
		int n=0;
		System.out.println("\n There are " + solution.size() + " moves to execute  \n\n");
		for(Action a : solution)
		{
			TileAction ta = (TileAction)a;
			TileActionEnum te = (TileActionEnum) ta.actionEnumSelected;
			System.out.print(te.getOpposite().toGraphical() + "  " );
			n++;
			if(n==15)
			{
				n=0;
				System.out.println("\n");
			}
			
		}
		System.out.println("\n\n");
		
	}
	
	

}
